package com.platform.common.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

/**
 * <pre>
 * 功能：zip压缩通用类
 * </pre>
 * 
 * @author wei.gao
 */
public class ZipUtils {
	
	/**
	 * <pre>
	 * 功能：压缩字符串
	 * </pre>
	 * 
	 * @param str
	 * @return
	 * @throws IOException
	 */
	public static String zip(String str) throws IOException {
		if (ValidateUtils.isNull(str)) {
			return str;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPOutputStream gzip = new GZIPOutputStream(out);
		gzip.write(str.getBytes());
		gzip.close();
		return out.toString(Configuration.getEncoding());
	}
	
	/**
	 * <pre>
	 * 功能：解压缩字符串
	 * </pre>
	 * 
	 * @param str
	 * @return
	 * @throws IOException
	 */
	public static String unzip(String str) throws IOException {
		if (ValidateUtils.isNull(str)) {
			return str;
		}
		ByteArrayOutputStream out = null;
		ByteArrayInputStream in = null;
		try {
			out = new ByteArrayOutputStream();
			in = new ByteArrayInputStream(str.getBytes(Configuration.getEncoding()));
			GZIPInputStream gunzip = new GZIPInputStream(in);
			IOUtils.copy(gunzip, out);
			return out.toString();
		} finally {
			IOUtils.closeQuietly(out);
			IOUtils.closeQuietly(in);
		}
	}
	
	/**
	 * <pre>
	 * 功能：zip压缩
	 * </pre>
	 * 
	 * @param zipFilePath
	 * @param files
	 * @throws IOException
	 */
	public static void zip(String zipFilePath, String[] files) throws IOException {
		zip(zipFilePath, files, Configuration.getEncoding());
	}
	
	/**
	 * <pre>
	 * 功能：zip压缩
	 * </pre>
	 * 
	 * @param zipfilepath
	 * @param files
	 * @param encoding
	 * @throws IOException
	 */
	public static void zip(String zipfilepath, String[] files, String encoding) throws IOException {
		ZipOutputStream localZipOutputStream = null;
		FileOutputStream localFileOutputStream = null;
		CheckedOutputStream localCheckedOutputStream = null;
		try {
			localFileOutputStream = new FileOutputStream(zipfilepath);
			localCheckedOutputStream = new CheckedOutputStream(localFileOutputStream, new CRC32());
			localZipOutputStream = new org.apache.tools.zip.ZipOutputStream(localCheckedOutputStream);
			localZipOutputStream.setLevel(9);
			localZipOutputStream.setEncoding(encoding);
			for (int i = 0; i < files.length; ++i) {
				zipStreamEntity(localZipOutputStream, new File(files[i]));
			}
		} finally {
			IOUtils.closeQuietly(localZipOutputStream);
			IOUtils.closeQuietly(localCheckedOutputStream);
			IOUtils.closeQuietly(localFileOutputStream);
		}
	}
	
	/**
	 * <pre>
	 * 功能：zip压缩流
	 * </pre>
	 * 
	 * @param out
	 * @param files
	 * @param encoding
	 * @throws IOException
	 */
	public static void zipStream(OutputStream out, String[] files, String encoding) throws IOException {
		ZipOutputStream localZipOutputStream = null;
		CheckedOutputStream localCheckedOutputStream = null;
		try {
			localCheckedOutputStream = new CheckedOutputStream(out, new CRC32());
			localZipOutputStream = new ZipOutputStream(localCheckedOutputStream);
			localZipOutputStream.setEncoding(encoding);
			localZipOutputStream.setLevel(9);
			for (int i = 0; i < files.length; ++i) {
				zipStreamEntity(localZipOutputStream, new File(files[i]));
			}
		} finally {
			IOUtils.closeQuietly(localCheckedOutputStream);
			IOUtils.closeQuietly(localZipOutputStream);
		}
	}
	
	/**
	 * <pre>
	 * 功能：zip压缩Item
	 * </pre>
	 * 
	 * @param paramZipOutputStream
	 * @param localFile
	 * @throws IOException
	 */
	private static void zipStreamEntity(ZipOutputStream paramZipOutputStream, File localFile) throws IOException {
		if (!(localFile.exists())) {
			throw new IllegalArgumentException();
		}
		if (localFile.isDirectory()) {
			throw new IllegalArgumentException();
		}
		paramZipOutputStream.putNextEntry(new ZipEntry(localFile.getName()));
		FileInputStream localFileInputStream = new FileInputStream(localFile);
		IOUtils.copy(localFileInputStream, paramZipOutputStream);
		paramZipOutputStream.flush();
		IOUtils.closeQuietly(localFileInputStream);
	}
	
}